import os
import re
import math
from statcollector import *

#the ?: denotes a non-capturing grouping
floatRE = '[+-]?\d+(?:\.\d*)?(?:[e|E][+-]?\d+)?';
intRE = '[+-]?\d+';
stringRE = '\w+'

#settings
outputDir = 'output/'
stdout = 'stdout.txt'
problemExt = '.strips'

#problem specific items
problem = 'blocks2d_batch'
#problem = 'circlestack_batch4'
problemValues = {"numBlocks":"numBlocks = %s",
                 #"numCircles":"numCircles = %s",
                 "type":"planner = '%s'",
                 "heuristicWeighting":"heuristicWeighting = %s",
                 "heuristicTechnique":"heuristicTechnique = '%s'"#,
                 #"lazyMaxDepth":"lazyMaxDepth = %s"
                 }
stdoutValues = {}
#this is the index used to collect data
#indexKeys = ("numCircles","type","heuristicWeighting","heuristicTechnique","lazyMaxDepth")
#indexKeys = ("numCircles","type","heuristicWeighting","heuristicTechnique")
indexKeys = ("numBlocks","type","heuristicWeighting","heuristicTechnique")

logDir = outputDir + problem + '/'

def scanfToRe(scanfstr):
    s=scanfstr.replace('%d','('+intRE+')')
    s=s.replace('%f','('+floatRE+')')
    s=s.replace('%s','('+stringRE+')')
    return s

problemREs = dict((key,re.compile(scanfToRe(value))) for (key,value) in problemValues.iteritems())

def parse_problem(pfile):
    f = open(pfile,'r')
    res = dict()
    for line in f.readlines():
        for (key,re) in problemREs.iteritems():
            found = re.match(line.strip())
            if found != None:
                res[key] = found.group(1)
    f.close()
    print pfile+":",res
    return res

def parse_stdout(sfile):
    f = open(sfile,'r')
    res = dict()
    outerRE = re.compile("Completed (\w+) outer planning iterations.")
    parameterSamplesLine = "parameter samples: "
    planningLine = "* Motion planning precondition stats *"
    successLine = "Outputting solution path to"
    parsePlanning = 0

    planfailed = True
    outerIters = 0
    numTransitionSamples = 0
    numCompletedPlans = 0
    numFailedPlans = 0
    numActivePlans = 0
    sumPlanIters = 0
    for line in f.readlines():
        found = outerRE.match(line.strip())
        if found != None:
            outerIters=found.group(1)
        if parsePlanning > 0:
            if parsePlanning > 1:
                if len(line.strip())==0:
                    parsePlanning=0
                    continue
                (name,complete,failed,active,time) = line.strip().split()
                numCompletedPlans += int(complete)
                numFailedPlans += int(failed)
                numActivePlans += int(active)
                t = (int(complete)+int(failed)+int(active))*float(time)
                sumPlanIters += t
            parsePlanning += 1
            
        if line.strip().find(planningLine) == 0:
            parsePlanning = 1

        if line.strip().find(successLine) >= 0:
            planfailed=False
            
        if line.strip().find(parameterSamplesLine) == 0:
            dictstr = line.strip().replace(parameterSamplesLine,'')
            sampledict = eval(dictstr)
            numTransitionSamples += sum(sampledict.values())

    f.close()
    res['OuterIters'] = outerIters
    res['TransitionSamples'] = numTransitionSamples
    res['CompletePlans'] = numCompletedPlans
    res['ActivePlans'] = numActivePlans
    res['FailedPlans'] = numFailedPlans
    res['PlanIters'] = sumPlanIters
    res['Failed'] = planfailed
    print res
    return res

def scan(path,log):
    #a log is a dict from indices to dicts from name to StatCollector's
    items = parse_problem(path+'/'+problem+problemExt)
    items.update(parse_stdout(path+'/'+stdout))
    pathKey = tuple([items[key] for key in indexKeys])
    pathItems = log.setdefault(pathKey,dict())
    for (key,value) in items.iteritems():
        if key not in indexKeys:
            pathItems.setdefault(key,StatCollector()).collect(float(value))

#do the main work
log = {}
i = 1
while os.path.exists(logDir+str(i)):
    scan(logDir+str(i),log)
    i += 1

defaultOutputValues = ['OuterIters','TransitionSamples','CompletePlans','ActivePlans','FailedPlans','PlanIters','Failed']
outputValues = defaultOutputValues+stdoutValues.keys()
outputNames = [v+ext for v in outputValues for ext in '_mean','_std','_min','max']
f = open(outputDir+problem+'.csv','w')
f.write(','.join(list(indexKeys)+outputNames)+'\n')
for (key,value) in log.iteritems():
    f.write(','.join(key))
    f.write(',')
    values = []
    for k in outputValues:
        values += [value[k].mean,math.sqrt(max(value[k].var,0.0)),value[k].vmin,value[k].vmax]
    f.write(','.join([str(v) for v in values])+'\n')
f.close()
